/******************************************************************************\
    IO.cpp contains functions for log output.
    It's used with acm server. See main.cpp for details.
    Copyright (C) 2008  Victor Vinogradov (fly3333@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
\******************************************************************************/

#include <stdarg.h>
#include ".\Log.h"
#include ".\Time.h"

cSubLog::cSubLog( const cStdFile &log_file )
	: LogFile( log_file )
{
}

cSubLog::~cSubLog()
{
}

bool cLog::Create( const char file_name[], const char *mode )
{
	cStdFile log_file;
	if( !log_file.Open( file_name, mode ) )
		return false;
   cSubLog *sub_log;
   try
   {
      sub_log = new cSubLog( log_file );
   }
   catch( ... )
   {
      return false;
   }
   SwitchToSubObject( sub_log );
   return true;
}

void cLog::Destroy()
{
   SwitchToSubObject( NULL );
}

void cLog::WriteV( const char format[], va_list arg_list )
{
   cLocker locker( GetSubObject()->CriticalSection );
	GetSubObject()->LogFile.PrintfV( format, arg_list );
   GetSubObject()->LogFile.Flush();
}

void cLog::Write( const char format[], ... )
{
   va_list arg_list;
   va_start( arg_list, format );
   WriteV( format, arg_list );
   va_end( arg_list );
}

void cLog::WriteLineV( const char level[], const char format[], va_list arg_list )
{
   unsigned short year, month, day, hour, minute, second, millisecond;
   SplitTime( GetTime(), &year, &month, &day, NULL, &hour, &minute, &second, &millisecond );
   DWORD thread_id = GetCurrentThreadId();
   cLocker locker( GetSubObject()->CriticalSection );
   Write( "%02hu.%02hu.%04hu %02hu:%02hu:%02hu.%03hu TID%08lX [%s] ", day, month, year, hour, minute, second, millisecond, thread_id, level );
   WriteV( format, arg_list );
}

void cLog::WriteLine( const char level[], const char format[], ... )
{
   va_list arg_list;
   va_start( arg_list, format );
   WriteLineV( level, format, arg_list );
   va_end( arg_list );
}

void cLog::DebugV( const char format[], va_list arg_list )
{
   WriteLineV( "Debug", format, arg_list );
}

void cLog::Debug( const char format[], ... )
{
   va_list arg_list;
   va_start( arg_list, format );
   DebugV( format, arg_list );
   va_end( arg_list );
}

void cLog::InfoV( const char format[], va_list arg_list )
{
   WriteLineV( "Info", format, arg_list );
}

void cLog::Info( const char format[], ... )
{
   va_list arg_list;
   va_start( arg_list, format );
   InfoV( format, arg_list );
   va_end( arg_list );
}

void cLog::NoticeV( const char format[], va_list arg_list )
{
   WriteLineV( "Notice", format, arg_list );
}

void cLog::Notice( const char format[], ... )
{
   va_list arg_list;
   va_start( arg_list, format );
   NoticeV( format, arg_list );
   va_end( arg_list );
}

void cLog::WarningV( const char format[], va_list arg_list )
{
   WriteLineV( "Warning", format, arg_list );
}

void cLog::Warning( const char format[], ... )
{
   va_list arg_list;
   va_start( arg_list, format );
   WarningV( format, arg_list );
   va_end( arg_list );
}

void cLog::ErrorV( const char format[], va_list arg_list )
{
   WriteLineV( "Error", format, arg_list );
}

void cLog::Error( const char format[], ... )
{
   va_list arg_list;
   va_start( arg_list, format );
   ErrorV( format, arg_list );
   va_end( arg_list );
}
